package icasue.runninginvoke.task.proxy;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.web.client.RestTemplate;
import icasue.runninginvoke.task.redis.AsyncTaskOperate;

import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.concurrent.*;

/**
 * @Author: Qiao Hang
 * @CreateDate: 2020/11/10 下午1:28
 * @UpdateDate:
 * @Description:
 */
@Data
@NoArgsConstructor
public abstract class TaskProxyHolder{

    /**
     * HTTP_PREFIX init on TaskAdapterService.class,
     * content: [http://ip_local:port | http://localhost:port | http://serviceId].
     */
    public static String HTTP_PREFIX;
    protected static final String COMMON_INVOKE_API = "%s/running-invoke/commonInvoke";
    protected static ExecutorService executorService = null;

    protected static final List<ScheduleTaskProxy> scheduleBuffer = new CopyOnWriteArrayList<ScheduleTaskProxy>(){
        @Override
        public boolean remove(Object o) {
            boolean remove = super.remove(o);
            if(this.size() <= 0 && executorService != null){
                synchronized (this){
                    if(executorService != null && !executorService.isShutdown()){
                        executorService.shutdown();
                    }
                }
            }
            return remove;
        }
    };

    protected Integer port = -1;
    protected AsyncTaskOperate asyncTaskOperate;
    protected RestTemplate restTemplate;
    protected SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    protected TaskProxyHolder(AsyncTaskOperate asyncTaskOperate,RestTemplate restTemplate){
        this.asyncTaskOperate = asyncTaskOperate;
        this.restTemplate = restTemplate;
    }

    protected String touchLocalAddress(){
        String localHostIpDynamic;
        try {
            localHostIpDynamic = InetAddress.getLocalHost().getHostAddress() + ":" + port + "(local)";
        }catch (Throwable e){
            localHostIpDynamic = "127.0.0.1:" + port + "(local)";
        }
        return localHostIpDynamic;
    }

    protected String touchBalanceAddress(String taskId){
        String balanceHostPort = "Unavailable";
        String execute = asyncTaskOperate.getExecute(taskId);
        if(execute != null && JSON.isValidObject(execute)){
            JSONObject taskServiceMetadata = JSON.parseObject(execute, JSONObject.class);
            String host = taskServiceMetadata.getString("host");
            String port = taskServiceMetadata.getString("port");
            balanceHostPort = String.join(":",host,port);
        }
        return balanceHostPort;
    }

    abstract protected void nextTrigger();
    abstract protected Object executeBalance();
    abstract protected void init();
    abstract protected Object execute();

}
